package com.trustbook.visitor.activity;

import java.io.ByteArrayOutputStream;
import java.io.File;

import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.trustbook.visitor.log.LogManager;
import com.trustbook.visitor.util.CameraUtil;
import com.trustbook.visitor.util.FileUtil;
import com.trustbook.visitor.value.Greeting;
import com.trustbook.visitor.value.MobileVisitor;

/**
 * 
 * @author Rahul_Mittal
 * 
 */
// Adding the action bar when running on versions older than Android 3.0 (down
// to Android 2.1) requires
// that you include the Android Support Library in your application.
public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks {

	private static String TAG = "MainActivity";
	public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";

	/**
	 * Fragment managing the behaviors, interactions and presentation of the
	 * navigation drawer.
	 */
	private NavigationDrawerFragment mNavigationDrawerFragment;

	/**
	 * Used to store the last screen title. For use in
	 * {@link #restoreActionBar()}.
	 */
	private CharSequence mTitle;

	private static final int CAMERA_REQUEST = 1888;
	private static final int CHOOSEGALLERY = 20000;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		LogManager.debug(TAG, "onCreate");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
		mTitle = getTitle();

		// Set up the drawer.
		mNavigationDrawerFragment.setUp(R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout));
	}

	@Override
	public void onNavigationDrawerItemSelected(int position) {
		LogManager.debug(TAG, "onNavigationDrawerItemSelected  position :" + position);
		// update the main content by replacing fragments, position starts from
		// 0,1,2.. and so on
		FragmentManager fragmentManager = getSupportFragmentManager();
		switch (position) {
		case 0:
			fragmentManager.beginTransaction().replace(R.id.container, VerificationFormFragment.newInstance(position)).commit();
			break;
		case 1:
			Intent intent = new Intent(this, SpyVideoRecorderActivity.class);
			intent.putExtra(EXTRA_MESSAGE, "" + position);
			startActivity(intent);
			break;
		case 2:
			fragmentManager.beginTransaction().replace(R.id.container, VerificationFormFragment.newInstance(position)).commit();
			break;
		default:
			fragmentManager.beginTransaction().replace(R.id.container, VerificationFormFragment.newInstance(position)).commit();
			break;
		}

	}

	public void onSectionAttached(int number) {
		switch (number) {
		case 1:
			mTitle = getString(R.string.title_section1);
			break;
		case 2:
			mTitle = getString(R.string.title_section2);
			break;
		case 3:
			mTitle = getString(R.string.title_section3);
			break;
		}
	}

	public void restoreActionBar() {
		ActionBar actionBar = getSupportActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
		actionBar.setDisplayShowTitleEnabled(true);
		actionBar.setTitle(mTitle);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		if (!mNavigationDrawerFragment.isDrawerOpen()) {
			// Only show items in the action bar relevant to this screen
			// if the drawer is not showing. Otherwise, let the drawer
			// decide what to show in the action bar.
			getMenuInflater().inflate(R.menu.main, menu);
			restoreActionBar();
			return true;
		}
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.

		switch (item.getItemId()) {
		case R.id.action_search:
			Toast.makeText(this, "Search...", Toast.LENGTH_SHORT).show();
			return true;
		case R.id.action_example:
			Toast.makeText(this, "Help...", Toast.LENGTH_SHORT).show();
			return true;
		case R.id.action_settings:
			Toast.makeText(this, "Settings...", Toast.LENGTH_SHORT).show();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}

	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class VerificationFormFragment extends Fragment {
		/**
		 * The fragment argument representing the section number for this
		 * fragment.
		 */
		private static final String ARG_SECTION_NUMBER = "section_number";

		/**
		 * Returns a new instance of this fragment for the given section number.
		 */
		public static VerificationFormFragment newInstance(int sectionNumber) {
			LogManager.debug(TAG, "PlaceholderFragment:newInstance :: inputParam:sectionNumber :" + sectionNumber);
			VerificationFormFragment fragment = new VerificationFormFragment();
			Bundle args = new Bundle();
			args.putInt(ARG_SECTION_NUMBER, sectionNumber);
			fragment.setArguments(args);
			return fragment;
		}

		public VerificationFormFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			LogManager.debug(TAG, "PlaceholderFragment:onCreateView() callled.");
			View rootView = null;
			if (getArguments().getInt(ARG_SECTION_NUMBER) == 0) {
				rootView = inflater.inflate(R.layout.fragment_entry_form, container, false);
			} else {
				rootView = inflater.inflate(R.layout.fragment_main, container, false);
				TextView textView = (TextView) rootView.findViewById(R.id.section_label);
				textView.setText("Section cliked : " + Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
			}

			// Button submitbutton = (Button)
			// rootView.findViewById(R.id.submit_form);
			// submitbutton.setOnClickListener(new View.OnClickListener() {
			// public void onClick(View v) {
			// submitFormData();
			// }
			// });
			return rootView;
		}

		@Override
		public void onAttach(Activity activity) {
			LogManager.debug(TAG, "PlaceholderFragment:onAttach() called. Activity :" + activity);
			super.onAttach(activity);
			((MainActivity) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
		}

	}// end fragment class

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		LogManager.debug(TAG, "onActivityResult() called. requestCode :" + requestCode + " resultCode :" + resultCode + " intent :" + intent);
		if (intent == null) {
			LogManager.debug(TAG, "Intent Null -> to returning back.");
			return;
		}
		// get the extras passed via intent parameter.
		Bundle extras = intent.getExtras();
		LogManager.debug(TAG, "--> Bundle extras :" + extras);
		Bitmap bmp = null;
		switch (requestCode) {
		case CAMERA_REQUEST:
			LogManager.debug(TAG, "Image Capture by Camera.");
			if (extras != null) {
				LogManager.debug(TAG, "CAMERA_REQUEST->intent.get(data) :" + intent.getData());
				LogManager.debug(TAG, "CAMERA_REQUEST->iintent.getExtras().get(\"data\") :" + intent.getExtras().get("data"));
				bmp = (Bitmap) extras.get("data");
			}

			if (bmp == null) {
				Uri selectedImage = intent.getData();
				String[] filePathColumn = { MediaStore.Images.Media.DATA };
				Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
				cursor.moveToFirst();
				int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
				// ***Here is stored the path***/
				String stringImagePath = cursor.getString(columnIndex);
				LogManager.debug(TAG, "CAMERA_REQUEST222:->Image path :" + stringImagePath);
				cursor.close();
				File image_file = new File(stringImagePath);
				bmp = FileUtil.decodeFile(image_file);
			}
			break;
		case CHOOSEGALLERY:
			LogManager.debug(TAG, "Image selected from Gallery.");
			if (resultCode == Activity.RESULT_OK) {
				Uri selectedImage = intent.getData();
				if (selectedImage != null) {
					LogManager.debug(TAG, "1:-> selectedImage.getPath() :" + selectedImage.getPath());
					String[] filePathColumn = { MediaStore.Images.Media.DATA };
					Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
					cursor.moveToFirst();
					int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
					String stringImagePath = cursor.getString(columnIndex); // here
																			// is
																			// stored
																			// the
																			// path
					LogManager.debug(TAG, "2:->Image path :" + stringImagePath);
					cursor.close();
					File image_file = new File(stringImagePath);
					try {
						// b64 = null;
						bmp = FileUtil.decodeFile(image_file);
						// if (bmp == null) {
						// this.showErrorAlert("Error",
						// "Error Loading image. Please try another method.",
						// true,
						// true);
						// break;
						// }
						LogManager.debug(TAG, "decoded-> Bitmap bmp :" + bmp);
					} catch (Exception e) {
						LogManager.debug(TAG, "---------->Excpetion while adding image ... ");
						LogManager.error(TAG, e.getMessage(), e);
						try {
							// b64 = null;
							bmp = Media.getBitmap(getContentResolver(), selectedImage);
							// if (bmp == null) {
							// this.showErrorAlert("Error",
							// "Error Loading image. Please try another method.",
							// true,
							// true);
							// break;
							// }
							LogManager.debug(TAG, "decoded-> Bitmap bmp :" + bmp);
						} catch (Exception ex) {
							LogManager.debug(TAG, "---------->Excpetion while adding image ... ");
							LogManager.error(TAG, ex.getMessage(), ex);
							// this.showErrorAlert("Error",
							// "Error Loading image. Please try another method.",
							// true,
							// true);
						}
					}
				} else {
					LogManager.error(TAG, "Gallery not available.", new Exception("Unable to load image from Gallery"));
					// this.showErrorAlert("Error",
					// "Error Loading image. Please try another method.", true,
					// true);
				}
			}

			break;
		}
		// Load the image in Async task.
		if (requestCode == CAMERA_REQUEST || requestCode == CHOOSEGALLERY) {
			LoadImageTask task = new LoadImageTask(bmp);
			task.execute();
		}
	}

	/**
	 * Load the image in async task.
	 * 
	 * @author Rahul_Mittal
	 * 
	 */
	public class LoadImageTask extends AsyncTask<Void, Void, Boolean> {

		private ProgressDialog dialog = new ProgressDialog(MainActivity.this);
		Bitmap bmpphoto;
		String b64 = null;

		public LoadImageTask(Bitmap bmp) {
			this.bmpphoto = bmp;
		}

		@Override
		protected void onPreExecute() {
			dialog.setMessage("Loading...");
			dialog.show();
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			LogManager.debug(TAG, "LoadImageTask:doInBackground() bmpphoto :" + bmpphoto);
			int scaledDown_size = (bmpphoto.getRowBytes() * bmpphoto.getHeight()) / 1024;
			LogManager.debug(TAG, "Enter doInBackground() image size :" + scaledDown_size + " (kb)");
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int quality = 70;
			boolean flag = false;
			if (scaledDown_size >= 2 * 1024) {
				quality = 50;
			} else if (scaledDown_size >= 1024 && scaledDown_size < 2 * 1024) {
				quality = 60;
			} else if (scaledDown_size >= 512 && scaledDown_size < 1024) {
				quality = 65;
			} else if (scaledDown_size >= 200 && scaledDown_size <= 512) {
				quality = 70;
			} else if (scaledDown_size >= 100 && scaledDown_size <= 200) {
				quality = 75;
			} else if (scaledDown_size <= 100) {
				quality = 80;
			}
			LogManager.debug(TAG, "quality of compression :" + quality);
			flag = bmpphoto.compress(Bitmap.CompressFormat.JPEG, quality, baos);

			LogManager.debug(TAG, "->Able to compress : " + flag);
			byte[] b = baos.toByteArray();
			b64 = Base64.encodeToString(b, Base64.DEFAULT);
			LogManager.debug(TAG, "Length of encoded image after compression(" + quality + "):" + b64.length() / 1024 + "(kb)");
			LogManager.debug(TAG, "Exit doInBackground() image size :" + (bmpphoto.getRowBytes() * bmpphoto.getHeight()) / 1024 + " (kb)");
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			dialog.dismiss();

			loadImage((ImageView) findViewById(R.id.imgview1), bmpphoto, 1, null, null, "", "");
			// findViewById(R.id.part_header1).requestFocus();

		}

		/**
		 * Load the image in image view
		 * 
		 * @param imgvw
		 *            - view against which image to be loaded.
		 * @param bp
		 *            - bitmap which is to be assigned.
		 * @param value
		 *            - image Id
		 * @param linearview
		 *            - view holder for image view -> to make it VISIBLE.
		 * @param addimage
		 *            - add image button to hide - > to make it GONE.
		 * @param base64
		 *            - base 64 string for image.
		 * @param imgName
		 *            - image name
		 */
		public void loadImage(ImageView imgvw, Bitmap bp, int value, View linearview, View addimage, String base64, String imgName) {

			LogManager.debug(TAG, "after resizing bmp size : " + base64.length() / 1024 + "(kb)");
			DisplayRunnable displayRunnable = new DisplayRunnable(bp, imgvw, value);
			handler.post(displayRunnable);
			// imgvw.setImageBitmap(bp);
			// imgvw.setTag(value);
			// linearview.setVisibility(View.VISIBLE);
			// addimage.setVisibility(View.GONE);
		}

	}

	private final Handler handler = new Handler();

	/**
	 * Display a bitmap in an image view on the ui thread which will be captured
	 * by camera.
	 */
	class DisplayRunnable implements Runnable {
		Bitmap bitmap;
		ImageView imageView;
		int tagvalue;

		public DisplayRunnable(Bitmap bmp, ImageView i, int value) {
			bitmap = bmp;
			imageView = i;
			tagvalue = value;
		}

		@Override
		public void run() {
			if (bitmap != null) {
				imageView.setImageBitmap(bitmap);
				imageView.setTag(tagvalue);
				Animation a = imageView.getAnimation();
				if (a != null) {
					a.reset();
					a.setStartTime(-1);
				} else
					a = AnimationUtils.loadAnimation(imageView.getContext(), R.anim.alpha_in_anim_quick);
				imageView.setAnimation(a);
				imageView.setVisibility(View.VISIBLE);
			} else {
				imageView.setImageBitmap(null);
				imageView.setVisibility(View.INVISIBLE);
			}
		}
	}

	/**
	 * 
	 * @param imagebutton
	 */
	public void onAddImgClick(View imagebutton) {
		LogManager.debug(TAG, "onAddImgClick() called.");
		if (CameraUtil.isIntentAvailable(this, android.provider.MediaStore.ACTION_IMAGE_CAPTURE)) {
			Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
			startActivityForResult(i, CAMERA_REQUEST);
		} else {
			Toast.makeText(this, "Image capture not available on device.", Toast.LENGTH_SHORT).show();
		}

	}

	/**
	 * 
	 * @param imagebutton
	 */
	public void onSubmitPressed(View imagebutton) {
		Toast.makeText(this, "fetching REst data", Toast.LENGTH_SHORT).show();
		new HttpRequestTask().execute();
	}

	private class HttpRequestTask extends AsyncTask<Void, Void, MobileVisitor> {
		@Override
		protected MobileVisitor doInBackground(Void... params) {
			try {
				final String url = "http://10.117.73.149:8080/visitors";
				RestTemplate restTemplate = new RestTemplate();
				LogManager.debug(TAG, "Adding converter.....................");
				restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
				LogManager.debug(TAG, " converter added.....................");
				MobileVisitor visitor = restTemplate.getForObject(url, MobileVisitor.class);
				return visitor;
			} catch (Exception e) {
				LogManager.error(TAG, e.getMessage(), e);
			}
			return null;
		}

		@Override
		protected void onPostExecute(MobileVisitor visitor) {
			LogManager.debug(TAG, " MobileVisitor : \n" + visitor);

		}

	}

	/**
	 * 
	 * @param imagebutton
	 */
	public void onGalleryClick(View imagebutton) {
		LogManager.debug(TAG, "onGalleryClick() called.");
		Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		i.setType("image/*");
		startActivityForResult(i, CHOOSEGALLERY);
	}
}
